package com.zhouyu;

import com.zhouyu.mapper.OrderMapper;
import com.zhouyu.mapper.UserMapper;
import com.zhouyu.mybatis.spring.ZhouyuFactoryBean;
import com.zhouyu.service.*;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.io.Resource;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

// 我的微信：dadudu6789
// 我的公众号：IT周瑜
public class Test {

	public static void main(String[] args) throws IOException {

		// 创建一个Spring容器
		//AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

		//不支持重复刷新
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

		//UserService userService = (UserService) applicationContext.getBean("userService");
		//userService.test();

		AsyncUserService asyncUserService = (AsyncUserService) applicationContext.getBean("asyncUserService");
		asyncUserService.test();


		//UserService userService = (UserService) applicationContext.getBean("userService");
		//userService.async();

		//MemberService userService = (MemberService) applicationContext.getBean("memberService");
		//userService.test();

		/**
		 * 上节课总结:
		 * 	   Advisor
		 * 	   	  Pointcut
		 * 	   	  	 ClassFilter
		 * 	   	  	 MethodMatcher
		 * 	   	  Advice ----> Method 拦截器
		 *
		 * 	UserService --->找到所有匹配的Advisor----->利用ProxyFactory生成代理对象
		 * 	代理对象执行某个方法时----->依据当前调用的方法---->找到所匹配的Advisor----->并执行对应的Advice逻辑
		 */

		//支持重复刷新
		//AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();

		//applicationContext.register(AppConfig.class);

		//applicationContext.getEnvironment().setRequiredProperties("ggg");

		//applicationContext.addBeanFactoryPostProcessor(new ZhouyuBeanFactoryPostProcessor());


		//applicationContext.refresh();

		//applicationContext.publishEvent("123");
		//applicationContext.register(AppConfig.class);
		//
		//
		//////是否支持循环依赖，默认是true
		////applicationContext.setAllowCircularReferences(false);
		//
		//AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		//beanDefinition.setBeanClass(UserService.class);
		//
		//beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(new OrderService());
		////beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(1, new OrderService());
		//beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(1, new RuntimeBeanReference("orderService"));
		//beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
		////宽松模式,默认是true
		//beanDefinition.setLenientConstructorResolution(false);

		//beanDefinition.setInstanceSupplier(new Supplier<Object>() {
		//	@Override
		//	public Object get() {
		//		return new E();
		//	}
		//});

		//applicationContext.registerBeanDefinition("userService", beanDefinition);


		//applicationContext.refresh();

		//applicationContext.registerShutdownHook();

		//ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");

		//AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
		//applicationContext.register(AppConfig.class);
		//applicationContext.register(AppConfig2.class);
		//applicationContext.refresh();

		////编程式BeanDefinition
		//AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		//beanDefinition.setBeanClass(UserService.class);
		//beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
		////beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON);
		//beanDefinition.setLazyInit(Boolean.FALSE);
		//applicationContext.registerBeanDefinition("userService", beanDefinition);

		//AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(applicationContext);
		////将User.class解析为BeanDefinition
		//annotatedBeanDefinitionReader.register(User.class);

		//XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
		//int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
		//
		//System.out.println(applicationContext.getBean("user"));

		//ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext);
		//scanner.scan("com.zhouyu");
		//System.out.println(applicationContext.getBean("userService"));

		//userService.b("aaa", "bbb");

		//UserServiceInterface userService = (UserServiceInterface) applicationContext.getBean("userService");
		//userService.xxxx();

		//AService aService = (AService) applicationContext.getBean("AService");
		//aService.test();

		//new Thread(() -> {
		//
		//	AService aService = (AService) applicationContext.getBean("AService");
		//}).start();
		//
		//
		//try {
		//	TimeUnit.SECONDS.sleep(3);
		//} catch (InterruptedException e) {
		//	e.printStackTrace();
		//}
		//
		//new Thread(() -> {
		//
		//	AService aService = (AService) applicationContext.getBean("AService");
		//	System.out.println(aService);
		//}).start();

		//ProductService productService = (ProductService) applicationContext.getBean("productService");
		//productService.test();
		//
		//applicationContext.close();

		//System.out.println(applicationContext.getBean("userService"));
		//System.out.println(applicationContext.getBean("userService"));
		//System.out.println(applicationContext.getBean("userService"));

		//ABTest abTest = (ABTest) applicationContext.getBean("ABTest");
		//System.out.println(abTest);

		//BaseService baseService = (BaseService) applicationContext.getBean("baseService");
		//baseService.a();

		//EmployeeService employeeService = (EmployeeService) applicationContext.getBean("employeeService");
		//employeeService.test();
		//employeeService.test();
		//employeeService.test();
		//
		//System.out.println("============================");
		//
		//employeeService.test2();
		//employeeService.test2();
		//employeeService.test2();

		//System.out.println(applicationContext.getBean("zhouyuFactoryBean"));
		//System.out.println(applicationContext.getBean("&zhouyuFactoryBean"));
		//System.out.println(applicationContext.getBean("&&&zhouyuFactoryBean"));

		////java中的类型转换器
		//StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();
		//propertyEditor.setAsText("1");
		//User user = (User) propertyEditor.getValue();
		//System.out.println(user);


		////Spring中的类型转换器
		//DefaultConversionService conversionService = new DefaultConversionService();
		//conversionService.addConverter(new StringToUserConverter());
		//User value = conversionService.convert("1", User.class);
		//System.out.println(value);

		//SimpleTypeConverter typeConverter = new SimpleTypeConverter();
		//typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor());
		////typeConverter.setConversionService(conversionService);
		//User user = typeConverter.convertIfNecessary("1", User.class);
		//System.out.println(user);

		//System.out.println(applicationContext.getMessage("test", null, new Locale("en")));

		//Resource resource = applicationContext.getResource("file://D:\\develop\\IdeaProjects\\spring-framework-5.3.10\\tuling\\src\\main\\java\\com\\zhouyu\\AppConfig.java");
		//System.out.println(resource.contentLength());
		//System.out.println(resource.getFilename());
		//
		//Resource resource1 = applicationContext.getResource("https://www.baidu.com");
		//System.out.println(resource1.contentLength());
		//System.out.println(resource1.getURL());
		//
		//Resource resource2 = applicationContext.getResource("classpath:spring.xml");
		//System.out.println(resource2.contentLength());
		//System.out.println(resource2.getURL());

		////操作系统环境变量
		//applicationContext.getEnvironment().getSystemEnvironment().forEach((k, v) -> {
		//	System.out.println(k + "-------->" + v);
		//});
		//
		//System.out.println("====================");
		//
		////获取JVM中的系统属性
		//applicationContext.getEnvironment().getSystemProperties().forEach((k, v) -> {
		//	System.out.println(k + "-------->" + v);
		//});
		//
		//System.out.println("====================");
		//
		//MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
		//System.out.println(propertySources);
		//
		//System.out.println("======================");
		//
		//
		//System.out.println(applicationContext.getEnvironment().getProperty("NO_PROXY"));
		//System.out.println(applicationContext.getEnvironment().getProperty("sun.jnu.encoding"));
		////获取spring.properties的属性值
		//System.out.println(applicationContext.getEnvironment().getProperty("zhouyu"));

		//DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
		//AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		//
		//beanDefinition.setBeanClass(User.class);
		//
		//beanFactory.registerBeanDefinition("user", beanDefinition);
		//System.out.println(beanFactory.getBean("user"));


//		UserService userService1 = new UserService();
//
//		for (Field field : userService1.getClass().getDeclaredFields()) {
//			if (field.isAnnotationPresent(Autowired.class)) {
//				field.set(userService1, ??);
//			}
//		}
//
//
//		for (Method method : userService1.getClass().getDeclaredMethods()) {
//			if (method.isAnnotationPresent(PostConstruct.class)) {
//				method.invoke(userService1, null);
//			}
//		}
//
//		if (userService1 instanceof InitializingBean) {
//			try {
//				((InitializingBean)userService1).afterPropertiesSet();
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		}
//
//		ProxyFactory proxyFactory = new ProxyFactory();
//		proxyFactory.setTarget(userService1);
//		proxyFactory.addAdvice(new MethodInterceptor() {
//			@Nullable
//			@Override
//			public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
//				System.out.println("切面逻辑 before...");
//				Object result = invocation.proceed();
////				Object result = invocation.getMethod().invoke(invocation.getThis(), invocation.getArguments());
//				System.out.println("切面逻辑 after...");
//				return result;
//			}
//		});
//		UserService userService2  = (UserService) proxyFactory.getProxy();
//		userService2.test();

	}
}







